﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x0200018E RID: 398
	[HelpURL("https://www.youtube.com/watch?v=r5jiZnsDH3M")]
	[AddComponentMenu("Scripts/RootMotion.FinalIK/Interaction System/Interaction Object")]
	public class InteractionObject : MonoBehaviour
	{
		// Token: 0x06000805 RID: 2053 RVA: 0x0002C4C1 File Offset: 0x0002A8C1
		[ContextMenu("TUTORIAL VIDEO (PART 1: BASICS)")]
		private void OpenTutorial1()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=r5jiZnsDH3M");
		}

		// Token: 0x06000806 RID: 2054 RVA: 0x0002C4CD File Offset: 0x0002A8CD
		[ContextMenu("TUTORIAL VIDEO (PART 2: PICKING UP...)")]
		private void OpenTutorial2()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=eP9-zycoHLk");
		}

		// Token: 0x06000807 RID: 2055 RVA: 0x0002C4D9 File Offset: 0x0002A8D9
		[ContextMenu("TUTORIAL VIDEO (PART 3: ANIMATION)")]
		private void OpenTutorial3()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=sQfB2RcT1T4&index=14&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
		}

		// Token: 0x06000808 RID: 2056 RVA: 0x0002C4E5 File Offset: 0x0002A8E5
		[ContextMenu("TUTORIAL VIDEO (PART 4: TRIGGERS)")]
		private void OpenTutorial4()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=-TDZpNjt2mk&index=15&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
		}

		// Token: 0x06000809 RID: 2057 RVA: 0x0002C4F1 File Offset: 0x0002A8F1
		[ContextMenu("Support Group")]
		private void SupportGroup()
		{
			Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
		}

		// Token: 0x0600080A RID: 2058 RVA: 0x0002C4FD File Offset: 0x0002A8FD
		[ContextMenu("Asset Store Thread")]
		private void ASThread()
		{
			Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
		}

		// Token: 0x170000A3 RID: 163
		// (get) Token: 0x0600080B RID: 2059 RVA: 0x0002C509 File Offset: 0x0002A909
		// (set) Token: 0x0600080C RID: 2060 RVA: 0x0002C511 File Offset: 0x0002A911
		public float length { get; private set; }

		// Token: 0x170000A4 RID: 164
		// (get) Token: 0x0600080D RID: 2061 RVA: 0x0002C51A File Offset: 0x0002A91A
		// (set) Token: 0x0600080E RID: 2062 RVA: 0x0002C522 File Offset: 0x0002A922
		public InteractionSystem lastUsedInteractionSystem { get; private set; }

		// Token: 0x0600080F RID: 2063 RVA: 0x0002C52C File Offset: 0x0002A92C
		public void Initiate()
		{
			for (int i = 0; i < this.weightCurves.Length; i++)
			{
				if (this.weightCurves[i].curve.length > 0)
				{
					float time = this.weightCurves[i].curve.keys[this.weightCurves[i].curve.length - 1].time;
					this.length = Mathf.Clamp(this.length, time, this.length);
				}
			}
			for (int j = 0; j < this.events.Length; j++)
			{
				this.length = Mathf.Clamp(this.length, this.events[j].time, this.length);
			}
			this.targets = this.targetsRoot.GetComponentsInChildren<InteractionTarget>();
		}

		// Token: 0x170000A5 RID: 165
		// (get) Token: 0x06000810 RID: 2064 RVA: 0x0002C601 File Offset: 0x0002AA01
		public Transform lookAtTarget
		{
			get
			{
				if (this.otherLookAtTarget != null)
				{
					return this.otherLookAtTarget;
				}
				return base.transform;
			}
		}

		// Token: 0x06000811 RID: 2065 RVA: 0x0002C624 File Offset: 0x0002AA24
		public InteractionTarget GetTarget(FullBodyBipedEffector effectorType, InteractionSystem interactionSystem)
		{
			if (interactionSystem.tag == string.Empty || interactionSystem.tag == string.Empty)
			{
				foreach (InteractionTarget interactionTarget in this.targets)
				{
					if (interactionTarget.effectorType == effectorType)
					{
						return interactionTarget;
					}
				}
				return null;
			}
			foreach (InteractionTarget interactionTarget2 in this.targets)
			{
				if (interactionTarget2.effectorType == effectorType && interactionTarget2.tag == interactionSystem.tag)
				{
					return interactionTarget2;
				}
			}
			return null;
		}

		// Token: 0x06000812 RID: 2066 RVA: 0x0002C6D8 File Offset: 0x0002AAD8
		public bool CurveUsed(InteractionObject.WeightCurve.Type type)
		{
			foreach (InteractionObject.WeightCurve weightCurve in this.weightCurves)
			{
				if (weightCurve.type == type)
				{
					return true;
				}
			}
			foreach (InteractionObject.Multiplier multiplier in this.multipliers)
			{
				if (multiplier.result == type)
				{
					return true;
				}
			}
			return false;
		}

		// Token: 0x06000813 RID: 2067 RVA: 0x0002C748 File Offset: 0x0002AB48
		public InteractionTarget[] GetTargets()
		{
			return this.targets;
		}

		// Token: 0x06000814 RID: 2068 RVA: 0x0002C750 File Offset: 0x0002AB50
		public Transform GetTarget(FullBodyBipedEffector effectorType, string tag)
		{
			if (tag == string.Empty || tag == string.Empty)
			{
				return this.GetTarget(effectorType);
			}
			for (int i = 0; i < this.targets.Length; i++)
			{
				if (this.targets[i].effectorType == effectorType && this.targets[i].tag == tag)
				{
					return this.targets[i].transform;
				}
			}
			return base.transform;
		}

		// Token: 0x06000815 RID: 2069 RVA: 0x0002C7DD File Offset: 0x0002ABDD
		public void OnStartInteraction(InteractionSystem interactionSystem)
		{
			this.lastUsedInteractionSystem = interactionSystem;
		}

		// Token: 0x06000816 RID: 2070 RVA: 0x0002C7E8 File Offset: 0x0002ABE8
		public void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, InteractionTarget target, float timer, float weight)
		{
			for (int i = 0; i < this.weightCurves.Length; i++)
			{
				float num = (!(target == null)) ? target.GetValue(this.weightCurves[i].type) : 1f;
				this.Apply(solver, effector, this.weightCurves[i].type, this.weightCurves[i].GetValue(timer), weight * num);
			}
			for (int j = 0; j < this.multipliers.Length; j++)
			{
				if (this.multipliers[j].curve == this.multipliers[j].result && !Warning.logged)
				{
					Warning.Log("InteractionObject Multiplier 'Curve' " + this.multipliers[j].curve.ToString() + "and 'Result' are the same.", base.transform, false);
				}
				int weightCurveIndex = this.GetWeightCurveIndex(this.multipliers[j].curve);
				if (weightCurveIndex != -1)
				{
					float num2 = (!(target == null)) ? target.GetValue(this.multipliers[j].result) : 1f;
					this.Apply(solver, effector, this.multipliers[j].result, this.multipliers[j].GetValue(this.weightCurves[weightCurveIndex], timer), weight * num2);
				}
				else if (!Warning.logged)
				{
					Warning.Log("InteractionObject Multiplier curve " + this.multipliers[j].curve.ToString() + "does not exist.", base.transform, false);
				}
			}
		}

		// Token: 0x06000817 RID: 2071 RVA: 0x0002C990 File Offset: 0x0002AD90
		public float GetValue(InteractionObject.WeightCurve.Type weightCurveType, InteractionTarget target, float timer)
		{
			int weightCurveIndex = this.GetWeightCurveIndex(weightCurveType);
			if (weightCurveIndex != -1)
			{
				float num = (!(target == null)) ? target.GetValue(weightCurveType) : 1f;
				return this.weightCurves[weightCurveIndex].GetValue(timer) * num;
			}
			for (int i = 0; i < this.multipliers.Length; i++)
			{
				if (this.multipliers[i].result == weightCurveType)
				{
					int weightCurveIndex2 = this.GetWeightCurveIndex(this.multipliers[i].curve);
					if (weightCurveIndex2 != -1)
					{
						float num2 = (!(target == null)) ? target.GetValue(this.multipliers[i].result) : 1f;
						return this.multipliers[i].GetValue(this.weightCurves[weightCurveIndex2], timer) * num2;
					}
				}
			}
			return 0f;
		}

		// Token: 0x170000A6 RID: 166
		// (get) Token: 0x06000818 RID: 2072 RVA: 0x0002CA6C File Offset: 0x0002AE6C
		public Transform targetsRoot
		{
			get
			{
				if (this.otherTargetsRoot != null)
				{
					return this.otherTargetsRoot;
				}
				return base.transform;
			}
		}

		// Token: 0x06000819 RID: 2073 RVA: 0x0002CA8C File Offset: 0x0002AE8C
		private void Awake()
		{
			this.Initiate();
		}

		// Token: 0x0600081A RID: 2074 RVA: 0x0002CA94 File Offset: 0x0002AE94
		private void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, InteractionObject.WeightCurve.Type type, float value, float weight)
		{
			switch (type)
			{
			case InteractionObject.WeightCurve.Type.PositionWeight:
				solver.GetEffector(effector).positionWeight = Mathf.Lerp(solver.GetEffector(effector).positionWeight, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.RotationWeight:
				solver.GetEffector(effector).rotationWeight = Mathf.Lerp(solver.GetEffector(effector).rotationWeight, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.PositionOffsetX:
				solver.GetEffector(effector).position += ((!(this.positionOffsetSpace != null)) ? solver.GetRoot().rotation : this.positionOffsetSpace.rotation) * Vector3.right * value * weight;
				return;
			case InteractionObject.WeightCurve.Type.PositionOffsetY:
				solver.GetEffector(effector).position += ((!(this.positionOffsetSpace != null)) ? solver.GetRoot().rotation : this.positionOffsetSpace.rotation) * Vector3.up * value * weight;
				return;
			case InteractionObject.WeightCurve.Type.PositionOffsetZ:
				solver.GetEffector(effector).position += ((!(this.positionOffsetSpace != null)) ? solver.GetRoot().rotation : this.positionOffsetSpace.rotation) * Vector3.forward * value * weight;
				return;
			case InteractionObject.WeightCurve.Type.Pull:
				solver.GetChain(effector).pull = Mathf.Lerp(solver.GetChain(effector).pull, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.Reach:
				solver.GetChain(effector).reach = Mathf.Lerp(solver.GetChain(effector).reach, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.Push:
				solver.GetChain(effector).push = Mathf.Lerp(solver.GetChain(effector).push, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.PushParent:
				solver.GetChain(effector).pushParent = Mathf.Lerp(solver.GetChain(effector).pushParent, value, weight);
				return;
			}
		}

		// Token: 0x0600081B RID: 2075 RVA: 0x0002CCB4 File Offset: 0x0002B0B4
		private Transform GetTarget(FullBodyBipedEffector effectorType)
		{
			for (int i = 0; i < this.targets.Length; i++)
			{
				if (this.targets[i].effectorType == effectorType)
				{
					return this.targets[i].transform;
				}
			}
			return base.transform;
		}

		// Token: 0x0600081C RID: 2076 RVA: 0x0002CD04 File Offset: 0x0002B104
		private int GetWeightCurveIndex(InteractionObject.WeightCurve.Type weightCurveType)
		{
			for (int i = 0; i < this.weightCurves.Length; i++)
			{
				if (this.weightCurves[i].type == weightCurveType)
				{
					return i;
				}
			}
			return -1;
		}

		// Token: 0x0600081D RID: 2077 RVA: 0x0002CD40 File Offset: 0x0002B140
		private int GetMultiplierIndex(InteractionObject.WeightCurve.Type weightCurveType)
		{
			for (int i = 0; i < this.multipliers.Length; i++)
			{
				if (this.multipliers[i].result == weightCurveType)
				{
					return i;
				}
			}
			return -1;
		}

		// Token: 0x0600081E RID: 2078 RVA: 0x0002CD7C File Offset: 0x0002B17C
		[ContextMenu("User Manual")]
		private void OpenUserManual()
		{
			Application.OpenURL("http://www.root-motion.com/finalikdox/html/page10.html");
		}

		// Token: 0x0600081F RID: 2079 RVA: 0x0002CD88 File Offset: 0x0002B188
		[ContextMenu("Scrpt Reference")]
		private void OpenScriptReference()
		{
			Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_interaction_object.html");
		}

		// Token: 0x040004FD RID: 1277
		[Tooltip("If the Interaction System has a 'Look At' LookAtIK component assigned, will use it to make the character look at the specified Transform. If unassigned, will look at this GameObject.")]
		public Transform otherLookAtTarget;

		// Token: 0x040004FE RID: 1278
		[Tooltip("The root Transform of the InteractionTargets. If null, will use this GameObject. GetComponentsInChildren<InteractionTarget>() will be used at initiation to find all InteractionTargets associated with this InteractionObject.")]
		public Transform otherTargetsRoot;

		// Token: 0x040004FF RID: 1279
		[Tooltip("If assigned, all PositionOffset channels will be applied in the rotation space of this Transform. If not, they will be in the rotation space of the character.")]
		public Transform positionOffsetSpace;

		// Token: 0x04000500 RID: 1280
		public InteractionObject.WeightCurve[] weightCurves;

		// Token: 0x04000501 RID: 1281
		public InteractionObject.Multiplier[] multipliers;

		// Token: 0x04000502 RID: 1282
		public InteractionObject.InteractionEvent[] events;

		// Token: 0x04000505 RID: 1285
		private InteractionTarget[] targets = new InteractionTarget[0];

		// Token: 0x0200018F RID: 399
		[Serializable]
		public class InteractionEvent
		{
			// Token: 0x06000821 RID: 2081 RVA: 0x0002CD9C File Offset: 0x0002B19C
			public void Activate(Transform t)
			{
				foreach (InteractionObject.AnimatorEvent animatorEvent in this.animations)
				{
					animatorEvent.Activate(this.pickUp);
				}
				foreach (InteractionObject.Message message in this.messages)
				{
					message.Send(t);
				}
			}

			// Token: 0x04000506 RID: 1286
			[Tooltip("The time of the event since interaction start.")]
			public float time;

			// Token: 0x04000507 RID: 1287
			[Tooltip("If true, the interaction will be paused on this event. The interaction can be resumed by InteractionSystem.ResumeInteraction() or InteractionSystem.ResumeAll;")]
			public bool pause;

			// Token: 0x04000508 RID: 1288
			[Tooltip("If true, the object will be parented to the effector bone on this event. Note that picking up like this can be done by only a single effector at a time. If you wish to pick up an object with both hands, see the Interaction PickUp2Handed demo scene.")]
			public bool pickUp;

			// Token: 0x04000509 RID: 1289
			[Tooltip("The animations called on this event.")]
			public InteractionObject.AnimatorEvent[] animations;

			// Token: 0x0400050A RID: 1290
			[Tooltip("The messages sent on this event using GameObject.SendMessage().")]
			public InteractionObject.Message[] messages;
		}

		// Token: 0x02000190 RID: 400
		[Serializable]
		public class Message
		{
			// Token: 0x06000823 RID: 2083 RVA: 0x0002CE0C File Offset: 0x0002B20C
			public void Send(Transform t)
			{
				if (this.recipient == null)
				{
					return;
				}
				if (this.function == string.Empty || this.function == string.Empty)
				{
					return;
				}
				this.recipient.SendMessage(this.function, t, SendMessageOptions.RequireReceiver);
			}

			// Token: 0x0400050B RID: 1291
			[Tooltip("The name of the function called.")]
			public string function;

			// Token: 0x0400050C RID: 1292
			[Tooltip("The recipient game object.")]
			public GameObject recipient;

			// Token: 0x0400050D RID: 1293
			private const string empty = "";
		}

		// Token: 0x02000191 RID: 401
		[Serializable]
		public class AnimatorEvent
		{
			// Token: 0x06000825 RID: 2085 RVA: 0x0002CE7C File Offset: 0x0002B27C
			public void Activate(bool pickUp)
			{
				if (this.animator != null)
				{
					if (pickUp)
					{
						this.animator.applyRootMotion = false;
					}
					this.Activate(this.animator);
				}
				if (this.animation != null)
				{
					this.Activate(this.animation);
				}
			}

			// Token: 0x06000826 RID: 2086 RVA: 0x0002CED8 File Offset: 0x0002B2D8
			private void Activate(Animator animator)
			{
				if (this.animationState == string.Empty)
				{
					return;
				}
				if (this.resetNormalizedTime)
				{
					animator.CrossFade(this.animationState, this.crossfadeTime, this.layer, 0f);
				}
				else
				{
					animator.CrossFade(this.animationState, this.crossfadeTime, this.layer);
				}
			}

			// Token: 0x06000827 RID: 2087 RVA: 0x0002CF40 File Offset: 0x0002B340
			private void Activate(Animation animation)
			{
				if (this.animationState == string.Empty)
				{
					return;
				}
				if (this.resetNormalizedTime)
				{
					animation[this.animationState].normalizedTime = 0f;
				}
				animation[this.animationState].layer = this.layer;
				animation.CrossFade(this.animationState, this.crossfadeTime);
			}

			// Token: 0x0400050E RID: 1294
			[Tooltip("The Animator component that will receive the AnimatorEvents.")]
			public Animator animator;

			// Token: 0x0400050F RID: 1295
			[Tooltip("The Animation component that will receive the AnimatorEvents (Legacy).")]
			public Animation animation;

			// Token: 0x04000510 RID: 1296
			[Tooltip("The name of the animation state.")]
			public string animationState;

			// Token: 0x04000511 RID: 1297
			[Tooltip("The crossfading time.")]
			public float crossfadeTime = 0.3f;

			// Token: 0x04000512 RID: 1298
			[Tooltip("The layer of the animation state (if using Legacy, the animation state will be forced to this layer).")]
			public int layer;

			// Token: 0x04000513 RID: 1299
			[Tooltip("Should the animation always start from 0 normalized time?")]
			public bool resetNormalizedTime;

			// Token: 0x04000514 RID: 1300
			private const string empty = "";
		}

		// Token: 0x02000192 RID: 402
		[Serializable]
		public class WeightCurve
		{
			// Token: 0x06000829 RID: 2089 RVA: 0x0002CFB5 File Offset: 0x0002B3B5
			public float GetValue(float timer)
			{
				return this.curve.Evaluate(timer);
			}

			// Token: 0x04000515 RID: 1301
			[Tooltip("The type of the curve (InteractionObject.WeightCurve.Type).")]
			public InteractionObject.WeightCurve.Type type;

			// Token: 0x04000516 RID: 1302
			[Tooltip("The weight curve.")]
			public AnimationCurve curve;

			// Token: 0x02000193 RID: 403
			[Serializable]
			public enum Type
			{
				// Token: 0x04000518 RID: 1304
				PositionWeight,
				// Token: 0x04000519 RID: 1305
				RotationWeight,
				// Token: 0x0400051A RID: 1306
				PositionOffsetX,
				// Token: 0x0400051B RID: 1307
				PositionOffsetY,
				// Token: 0x0400051C RID: 1308
				PositionOffsetZ,
				// Token: 0x0400051D RID: 1309
				Pull,
				// Token: 0x0400051E RID: 1310
				Reach,
				// Token: 0x0400051F RID: 1311
				RotateBoneWeight,
				// Token: 0x04000520 RID: 1312
				Push,
				// Token: 0x04000521 RID: 1313
				PushParent,
				// Token: 0x04000522 RID: 1314
				PoserWeight
			}
		}

		// Token: 0x02000194 RID: 404
		[Serializable]
		public class Multiplier
		{
			// Token: 0x0600082B RID: 2091 RVA: 0x0002CFD6 File Offset: 0x0002B3D6
			public float GetValue(InteractionObject.WeightCurve weightCurve, float timer)
			{
				return weightCurve.GetValue(timer) * this.multiplier;
			}

			// Token: 0x04000523 RID: 1315
			[Tooltip("The curve type to multiply.")]
			public InteractionObject.WeightCurve.Type curve;

			// Token: 0x04000524 RID: 1316
			[Tooltip("The multiplier of the curve's value.")]
			public float multiplier = 1f;

			// Token: 0x04000525 RID: 1317
			[Tooltip("The resulting value will be applied to this channel.")]
			public InteractionObject.WeightCurve.Type result;
		}
	}
}
